﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="IBuproMembershipProvider.cs" company="">
//   Copyright (c) 2010/2011 All Right Reserved
// </copyright>
// <summary>
//   Contains IBuproMembershipProvider interface declaration.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace iBuproModel.Providers
{
    using System;
    using System.Linq;
    using System.Web.Security;

    using iBuproModel;
    using iBuproModel.Classes;

    public class IBuproMembershipProvider : MembershipProvider
    {
        private Entities context;
        
        public IBuproMembershipProvider()
        {
            context = Repositories.ContextService.GetInstance;
        }

        public override string ApplicationName
        {
            get
            {
                return "ibupro";
            }

            set
            {
                throw new NotImplementedException();
            }
        }

        public override bool ChangePassword(string username, string oldPassword, string newPassword)
        {
            try
            {
                User user = this.context.Users.Where(u => u.Username == username).Single();

                string salt = user.Salt;
                string oldHash = Cryptography.GetSHA256(this.CombineSaltAndPassword(salt, oldPassword));
                string databaseHash = user.Password;

                if (oldHash == databaseHash)
                {
                    string newHash = Cryptography.GetSHA256(this.CombineSaltAndPassword(salt, newPassword));
                    user.Password = newHash;
                    this.context.SaveChanges();

                    return true;
                }
            }
            catch (Exception exp)
            {
                throw exp;
            }

            return false;
        }

        public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer)
        {
            throw new NotImplementedException();
        }

        public MembershipUser CreateUser(string username, string password, string email, string firstName, string lastName, out MembershipCreateStatus status)
        {
            try
            {
                int UsernameCount = context.Users.Where(u => u.Username == username).Count();

                if (UsernameCount > 0)
                {
                    status = MembershipCreateStatus.DuplicateUserName;
                    return null;
                }

                int EmailCount = this.context.Users.Where(u => u.Email == email).Count();

                if (EmailCount > 0)
                {
                    status = MembershipCreateStatus.DuplicateEmail;
                    return null;
                }


                User user = new User() 
                { 
                    Username = username, 
                    Password = password,
                    Email = email, 
                    FirstName = firstName,
                    LastName = lastName,
                    Salt = Cryptography.GenerateSalt(),
                };

                user.Password = Cryptography.GetSHA256(CombineSaltAndPassword(user.Salt, password));

                IBuproRoleProvider roles = new IBuproRoleProvider();
                if (!roles.RoleExists("Student"))
                    roles.CreateRole("Student");
                Role roleStudent = context.Roles.Where(r => r.Name == "Student").SingleOrDefault();


                this.context.AttachTo("Roles", roleStudent);



                roleStudent.Users.Add(user);

                this.context.SaveChanges();
                status = MembershipCreateStatus.Success;
                return null;
            }
            catch
            {
                throw new Exception("Cannot create user.");
            }
        }

        public override bool DeleteUser(string username, bool deleteAllRelatedData)
        {
            try
            {
                User user = context.Users.Where(u => u.Username == username).SingleOrDefault();
                
                if (user == null)
                    return false;

                context.Users.DeleteObject(user);
                context.SaveChanges();

                return true;
                

            }
            catch
            {
                throw new Exception("Cannot delete user");
            }

        }

        public override bool EnablePasswordReset
        {
            get { throw new NotImplementedException(); }
        }

        public override bool EnablePasswordRetrieval
        {
            get { throw new NotImplementedException(); }
        }

        public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords)
        {
            throw new NotImplementedException();
        }

        public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords)
        {
            throw new NotImplementedException();
        }

        public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)
        {
            throw new NotImplementedException();
            
        }

        public override int GetNumberOfUsersOnline()
        {
            throw new NotImplementedException();
        }

        public override string GetPassword(string username, string answer)
        {
            throw new NotImplementedException();
        }

        public override MembershipUser GetUser(string username, bool userIsOnline)
        {
            throw new NotImplementedException();
        }

       

        public override string GetUserNameByEmail(string email)
        {
            throw new NotImplementedException();
        }

        public override int MaxInvalidPasswordAttempts
        {
            get { throw new NotImplementedException(); }
        }

        public override int MinRequiredNonAlphanumericCharacters
        {
            get { return 0; }
        }

        public override int MinRequiredPasswordLength
        {
            get { return 0; }
        }

        public override int PasswordAttemptWindow
        {
            get { return 3; }
        }

        public override MembershipPasswordFormat PasswordFormat
        {
            get { throw new NotImplementedException(); }
        }

        public override string PasswordStrengthRegularExpression
        {
            get { throw new NotImplementedException(); }
        }

        public override bool RequiresQuestionAndAnswer
        {
            get { throw new NotImplementedException(); }
        }

        public override bool RequiresUniqueEmail
        {
            get { throw new NotImplementedException(); }
        }

        public override string ResetPassword(string username, string answer)
        {
            throw new NotImplementedException();
        }

        public override bool UnlockUser(string userName)
        {
            throw new NotImplementedException();
        }

        public override void UpdateUser(MembershipUser user)
        {
            throw new NotImplementedException();
        }

        public override bool ValidateUser(string username, string password)
        {
            try
            {
                User user = context.Users.Where(u => u.Username == username).SingleOrDefault();

                if (user == null)
                    return false;


                string hash = Cryptography.GetSHA256(CombineSaltAndPassword(user.Salt, password));

                if (user.Password == hash)
                {
                    return true;
                }
                else return false;
            }
            catch
            {
                throw new Exception("Cannot validate user");
            }
            
        }

        public string CombineSaltAndPassword(string salt, string password)
        {
            return salt + password;
        }

        public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
        {
            throw new NotImplementedException();
        }

        public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)
        {
            throw new NotImplementedException();
        }

        public bool UserExists(string username)
        {
            var user = context.Users.Where(u => u.Username == username).SingleOrDefault();
            if (user == null)
                return false;
            else return true;
        }
    }
}
